import random
import re
import time
from DrissionPage import ChromiumOptions, Chromium
from get_xy import Ddddocr
import base64
from DrissionPage.common import Actions
from PIL import Image
import io
import ddddocr


def scroll_code(tab, back_image_path: str = 'back_captcha.png',  bock_image_path: str = 'bock_captcha.png'):
    # 提取 base64 图像字符串
    try:
        back_img_ele = tab.ele('xpath://div[@class="verify-img-panel"]/img')
        bock_img_ele = tab.ele('xpath://div[@class="verify-sub-block"]/img')
        slider_btn = tab.ele('xpath://div[@class="verify-move-block"]')  # 滑块按钮
    except:
        return False

    back_base64_str = back_img_ele.attr('src')
    if not back_base64_str.startswith('data:image'):
        print('验证码图片不是 base64 格式！')
        return False
    bock_base64_str = bock_img_ele.attr('src')
    if not bock_base64_str.startswith('data:image'):
        print('验证码图片不是 base64 格式！')
        return False

    # 提取纯 base64 数据部分（去掉前缀）
    back_base64_data = back_base64_str.split(',', 1)[1]
    bock_base64_data = bock_base64_str.split(',', 1)[1]

    # 解码 base64 图片
    back_img_bytes = base64.b64decode(back_base64_data)
    bock_img_bytes = base64.b64decode(bock_base64_data)

    # 使用 PIL 打开图片，并调整尺寸
    back_img = Image.open(io.BytesIO(back_img_bytes))
    back_resized_img = back_img.resize((400, 200))  # 宽400，高200

    # 使用 PIL 打开图片，并调整尺寸
    bock_img = Image.open(io.BytesIO(bock_img_bytes))
    bock_resized_img = bock_img.resize((60, 200))  # 宽400，高200

    # 保存图片
    back_resized_img.save(back_image_path)
    bock_resized_img.save(bock_image_path)

    # img_bytes = base64.b64decode(base64_data)
    # with open(image_path, 'wb') as f:
    #     f.write(img_bytes)

    # 调用 OCR 获取文字和位置
    with open(back_image_path, 'rb') as f:
        back_img_bytes = f.read()

    with open(bock_image_path, 'rb') as f:
        bock_img_bytes = f.read()

    det = ddddocr.DdddOcr(det=False, ocr=False, show_ad=False)
    res = det.slide_match(bock_img_bytes, back_img_bytes, simple_target=True)
    gap_x = res['target'][0]

    # 获取验证码图在页面上的偏移
    slider_rect = slider_btn.rect.location
    slider_x, slider_y = slider_rect[0], slider_rect[1]
    # 计算需要滑动的距离（考虑滑块宽度）
    slider_width = slider_btn.rect.size
    # distance = gap_x - slider_width[0] / 2  # 减去滑块宽度的一半更精确
    distance = gap_x  # 减去滑块宽度的一半更精确

    # 初始化Actions对象
    ac = Actions(tab)

    # 模拟人类滑动：先快速移动大部分距离，再缓慢移动剩余距离
    # 1. 移动到滑块按钮上
    ac.move(slider_x + slider_width[0] / 2, slider_y + slider_width[0] / 2)

    # 2. 按下鼠标
    ac.hold()

    # 3. 分阶段移动
    # 快速移动80%距离
    fast_distance = distance * 0.8
    ac.move(fast_distance, 0, duration=0.3)
    time.sleep(round(random.uniform(0.1, 0.3), 2))

    # 慢速移动剩余20%距离
    slow_distance = distance * 0.2
    steps = int(slow_distance / 5)  # 分成小步移动
    for i in range(steps):
        ac.move(5, 0, duration=0.05)
        time.sleep(round(random.uniform(0.01, 0.03), 2))

    # 4. 释放鼠标
    ac.release()

    print(f"滑块验证完成，滑动距离: {distance}px")
    time.sleep(2)  # 等待验证结果
    return True


def click_code(tab, image_path: str = 'captcha.png'):
    try:
        img_ele = tab.ele('xpath://div[@class="verify-img-panel"]/img')
        text = tab.ele('xpath://span[@class="verify-msg"]').text
        text_ = re.findall('【(.*?)】', text)
        target_words = str(text_[0]).split(',')
    except:
        return False

    base64_str = img_ele.attr('src')
    if not base64_str.startswith('data:image'):
        raise ValueError('验证码图片不是 base64 格式！')

    # 提取纯 base64 数据部分（去掉前缀）
    base64_data = base64_str.split(',', 1)[1]

    # 解码 base64 图片
    img_bytes = base64.b64decode(base64_data)

    # 使用 PIL 打开图片，并调整尺寸
    img = Image.open(io.BytesIO(img_bytes))
    resized_img = img.resize((500, 255))  # 宽500，高255

    # 保存图片
    resized_img.save(image_path)

    # img_bytes = base64.b64decode(base64_data)
    # with open(image_path, 'wb') as f:
    #     f.write(img_bytes)

    # 调用 OCR 获取文字和位置
    ocr = Ddddocr()
    with open(image_path, 'rb') as f:
        img_bytes = f.read()
    # results = ocr.recognize_text_with_position(img_bytes)
    details = ocr.recognize_text_with_position(img_bytes)
    ocr_dict = {item["text"]: item for item in details}
    # sorted_ocr_lis = [ocr_dict[word]['center'] for word in wordList if word in ocr_dict]
    sorted_ocr_lis = [ocr_dict[word]['center'] for word in target_words if word in ocr_dict]
    print(ocr_dict)

    if len(sorted_ocr_lis) != 3:
        return False
    else:
        # 获取验证码图在页面上的偏移
        loc = img_ele.rect.location
        # 645，339
        base_x, base_y = loc[0], loc[1]
        # 初始化 Actions 对象
        # ac = Actions(tab)  # 传入 tab 对象作为参数
        for center in sorted_ocr_lis:
            ac = Actions(tab)
            cx, cy = center  # 直接解包坐标
            abs_x = base_x + cx
            abs_y = base_y + cy
            ac.move(abs_x, abs_y).click()  # 使用 Actions 的 move 和 click 方法
            time.sleep(round(random.uniform(0.4, 0.9), 2))

        print(f"验证点击完成：{details}")
        return True


def verify_page(url: str, tab):
    # 初始化浏览器和标签页
    # co = ChromiumOptions().auto_port()
    # browser = Chromium(co)
    # tab = browser.get_tab()

    # 打开页面并等待加载
    while True:
        # tab.get(url)
        tab.wait.load_start()
        time.sleep(2)
        if '拖动滑块完成拼图' in str(tab.html):
            res = scroll_code(tab)
            if res:
                tab.wait.load_start()
                time.sleep(2)
                # tab.close()
                break
            else:
                tab.get(url)
        elif '请依次点击' in str(tab.html):
            res = click_code(tab)
            if res:
                tab.wait.load_start()
                time.sleep(2)
                # tab.close()
                break
            else:
                tab.get(url)
        else:
            break


# if __name__ == '__main__':
#     verify_page('https://china.guidechem.com/product/listc_catid-2512-p3.html')